package com.binfenhulian.chinaenergy.ces.manage.service.content;

import com.binfenhulian.chinaenergy.ces.core.bean.enums.ExceptionDescEnum;
import com.binfenhulian.chinaenergy.ces.core.exception.BaseException;
import com.binfenhulian.chinaenergy.ces.manage.bean.param.ContentParam;
import com.binfenhulian.chinaenergy.ces.manage.bean.param.SessionParam;
import com.binfenhulian.chinaenergy.ces.manage.core.db.dao.auto.ContentDetailDAO;
import com.binfenhulian.chinaenergy.ces.manage.core.db.dao.auto.ContentDetailImageDAO;
import com.binfenhulian.chinaenergy.ces.manage.core.db.dao.auto.ContentRecordDAO;
import com.binfenhulian.chinaenergy.ces.manage.core.db.dao.def.ContentDefDAO;
import com.binfenhulian.chinaenergy.ces.manage.core.db.enums.ContentRecordTypeEnum;
import com.binfenhulian.chinaenergy.ces.manage.core.db.po.auto.*;
import com.binfenhulian.chinaenergy.ces.manage.core.url2io.bean.response.Url2IOResponse;
import com.binfenhulian.chinaenergy.ces.manage.core.url2io.executor.Url2IOExecutor;
import com.binfenhulian.chinaenergy.ces.manage.core.url2io.processor.BaseExtraProcessor;
import com.binfenhulian.chinaenergy.ces.manage.service.imports.ImportService;
import com.binfenhulian.chinaenergy.ces.manage.service.publish.PublishService;
import com.binfenhulian.chinaenergy.ces.manage.service.readedit.ReadEditService;
import com.binfenhulian.chinaenergy.ces.utils.date.UnixTimestampUtils;
import com.binfenhulian.chinaenergy.ces.utils.uuid.UuidUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by wanghjbuf on 2018/3/15.
 */
@Slf4j
@Service("com.binfenhulian.chinaenergy.ces.manage.service.content.ContentServiceImpl")
public class ContentServiceImpl implements ContentService{

    @Autowired
    ContentDefDAO contentDefDAO;
    @Autowired
    ContentRecordDAO contentRecordDAO;
    @Autowired
    ContentDetailImageDAO contentDetailImageDAO;
    @Autowired
    ContentDetailDAO contentDetailDAO;
    @Resource(name = "com.binfenhulian.chinaenergy.ces.manage.core.url2io.executor.Url2IOExecutor")
    Url2IOExecutor url2IOExecutor;
    @Resource(name = "com.binfenhulian.chinaenergy.ces.manage.core.url2io.processor.DownPicExtraProcessor")
    BaseExtraProcessor baseExtraProcessor;
    @Resource(name = "com.binfenhulian.chinaenergy.ces.manage.service.imports.ImportServiceImpl")
    ImportService importService;
    @Resource(name = "com.binfenhulian.chinaenergy.ces.manage.service.readedit.ReadEditServiceImpl")
    ReadEditService readEditService;
    @Resource(name = "com.binfenhulian.chinaenergy.ces.manage.service.publish.PublishServiceImpl")
    PublishService publishService;

    @Override
    public PageInfo listContentByPage(Map<String,Object> paramMap) throws BaseException{
        try {
            Page page = PageHelper.startPage(Integer.parseInt(paramMap.get("pageNum").toString()), Integer.parseInt(paramMap.get("pageSize").toString()));
            PageInfo pageInfo = new PageInfo(contentDefDAO.query(paramMap));
            return pageInfo;
        } catch (Exception e) {
            throw new BaseException(ExceptionDescEnum.BASE.getExceptionDesc(), e);
        }
    }

    @Override
    public ContentParam detailByRecordNo(String recordNo) throws BaseException {
        ContentParam result = new ContentParam();
        try {
            Map<String, Object> contentMap = contentDefDAO.queryDetails(recordNo);

            if (null != contentMap) {
                result.setId(Long.parseLong(contentMap.get("id").toString()));
                result.setTitle(contentMap.get("title").toString());
                result.setOriginalUrl(contentMap.get("originalUrl").toString());
                result.setReleaseTime(contentMap.get("releaseTime").toString());
                result.setContent(contentMap.get("content").toString());
                result.setSite(Integer.parseInt(contentMap.get("site").toString()));
                result.setAuthor(contentMap.get("author").toString());
                result.setRecordNo(recordNo);
            } else {
                ContentRecordPOExample contentRecordPOExample = new ContentRecordPOExample();
                contentRecordPOExample.createCriteria().andNoEqualTo(recordNo);
                List<ContentRecordPO> contentRecordPOList = contentRecordDAO.selectByExample(contentRecordPOExample);
                if (contentRecordPOList.size() == 1) {
                    ContentRecordPO curContentRecordPO = contentRecordPOList.get(0);
                    String beiginUrl = curContentRecordPO.getUrl();
                    result = extractData(beiginUrl);

                } else {
                    throw new BaseException("不存在对应的种子记录,操作失败!");
                }
            }
        } catch (BaseException e){
            throw e;
        } catch (Exception e) {
            throw new BaseException(ExceptionDescEnum.BASE.getExceptionDesc(), e);
        }
        return result;
    }

    /**
     * 提取数据
     * @param beginUrl
     * @return
     * @throws BaseException
     */
    private ContentParam extractData(String beginUrl) throws BaseException{
        ContentParam result = new ContentParam();
        List<Url2IOResponse> url2IOResponseList = url2IOExecutor.doExceute(beginUrl, baseExtraProcessor, null);

        if (null == url2IOResponseList || url2IOResponseList.size() > 1){
           throw new BaseException("数据提取过程发生未知错误,操作失败!");
        }else{
            Url2IOResponse curUrl2IOResponse = url2IOResponseList.get(0);
            result.setTitle(curUrl2IOResponse.getTitle());
            result.setOriginalUrl(curUrl2IOResponse.getUrl());
//            result.setReleaseTime(curUrl2IOResponse.getTitle());
            result.setContent(curUrl2IOResponse.getContent());
        }
        return result;
    }

    @Transactional
    @Override
    public int save(ContentParam contentParam, SessionParam sessionParam) throws BaseException{
        int resultCount = 0;
        try {
            ContentDetailPO contentDetailPO = new ContentDetailPO();
            BeanUtils.copyProperties(contentParam, contentDetailPO);
            contentDetailPO.setPublishCount(0);
            contentDetailPO.setReleaseTime(UnixTimestampUtils.converStringToUnixTimes("yyyy-MM-dd", contentParam.getReleaseTime()));

            if (contentParam.getId() == null){
                contentDetailPO.setNo(UuidUtils.getUUID());
                resultCount = contentDetailDAO.insertSelective(contentDetailPO);
            } else {
                resultCount = contentDetailDAO.updateByPrimaryKeySelective(contentDetailPO);
                contentDetailPO.setNo(contentDetailDAO.selectByPrimaryKey(contentParam.getId()).getNo());
            }

            /**
             * 添加正文缩略图
             */
            ContentDetailImagePOExample contentDetailImagePOExample = new ContentDetailImagePOExample();
            contentDetailImagePOExample.createCriteria().andContentNoEqualTo(contentDetailPO.getNo());
            contentDetailImageDAO.deleteByExample(contentDetailImagePOExample);

            String Regex="src=\".*?\"";
            String content = contentDetailPO.getContent();
            Pattern p=Pattern.compile(Regex);
            Matcher matcher=p.matcher(content);
            while (matcher.find()) {
                String src = matcher.group();
                String imageUrl = src.substring(4, src.length());
                log.info("imageUrl:{};", imageUrl);
                ContentDetailImagePO contentDetailImagePO = new ContentDetailImagePO();
                contentDetailImagePO.setContentNo(contentDetailPO.getNo());
                contentDetailImagePO.setCreateTime(UnixTimestampUtils.currentTimes());
                contentDetailImagePO.setImageUrl(imageUrl);
                contentDetailImageDAO.insertSelective(contentDetailImagePO);
            }

            contentDefDAO.useCountAdd(contentDetailPO.getRecordNo());
            readEditService.add(contentDetailPO.getRecordNo(), sessionParam.getName());
        } catch (BaseException e){
            throw e;
        } catch (Exception e) {
            throw new BaseException(ExceptionDescEnum.BASE.getExceptionDesc(), e);
        }
        return resultCount;
    }

    @Transactional
    @Override
    public void publish(String recordNo, SessionParam sessionParam) throws BaseException{
        try {
            //TODO 待确定导出方案

            contentDefDAO.publishCountAdd(recordNo);
            publishService.add(recordNo, sessionParam.getName());
        } catch (BaseException e){
            throw e;
        } catch (Exception e) {
            throw new BaseException(ExceptionDescEnum.BASE.getExceptionDesc(), e);
        }
    }

    @Transactional
    @Override
    public int addSeed(String title, String url, SessionParam sessionParam) throws BaseException {
        int resultCount = 0;
        try{
            String no = UuidUtils.getUUID();
            ContentRecordPO contentRecordPO = new ContentRecordPO();
            contentRecordPO.setNo(no);
            contentRecordPO.setCreateTime(UnixTimestampUtils.currentTimes());
            contentRecordPO.setFirstDiscovery(UnixTimestampUtils.currentTimes());
            contentRecordPO.setRecentlyDiscovery(UnixTimestampUtils.currentTimes());
            contentRecordPO.setUpdateTime(UnixTimestampUtils.currentTimes());
            contentRecordPO.setTitle(title);
            contentRecordPO.setUrl(url);
            contentRecordPO.setType(ContentRecordTypeEnum.SELF.name());
            contentRecordPO.setUseCount(0);
            contentRecordPO.setCrawlerNo("-1");

            importService.add(no, sessionParam.getName());
            resultCount = contentRecordDAO.insertSelective(contentRecordPO);
        }catch (Exception e) {
            throw new BaseException(ExceptionDescEnum.BASE.getExceptionDesc(), e);
        }
        return resultCount;
    }
}
